home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*------------------------------------------------------------------------------
- *
- * OORT - explosion.c - Routines for creating and displaying explosion.
- *
- * $Id: explosion.c,v 1.4 1994/01/28 00:17:49 mtj Exp $
- *
- * Chris Fouts - May, 1993.
- *
- *----------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <malloc.h>
- #include <gl.h>
- #include <Performer/pf.h>
-
- #include "oort.h"
- #include "explosion.h"
-
- #define EXPLOSION_SWITCH(g) (pfSwitch *)pfGetChild( (g), 0 )
-
-
-
- /* BEGIN PROTOTYPES -S explosion.c */
- static void createExplosions( int rings, int spokes, int frames ) ;
- static pfGeode * makeExplosionFrame( int rings, int spokes, float r,
- float frame ) ;
- /* END PROTOTYPES -S explosion.c */
-
- static pfGroup *baseExplosionGroup ;
- static pfSwitch *explosionSwitch ;
- static pfDCS *explosionDCS ;
- static pfGeoState *expGeoState ;
- static pfDCS *explosionGroup[MAXPLAYERS] ;
-
- extern float gameTime ;
- extern float deadTime[] ;
- extern float frameRate ;
- extern int debugOn ;
- extern pfGroup *trikeSwitch[] ;
- extern pfGroup *pShield[] ;
- extern pfGroup *vehicle[] ;
- extern pfMatrix playerMatrix[] ;
- extern pfMatrix selfMatrix ;
- extern pfVec3 ahead ;
- extern pfVec3 right ;
- extern pfVec3 up ;
- extern Player player[] ;
- extern int numberPlayers ;
-
- static struct {
- pfDCS *location ;
- pfGroup *frame ;
- } expNodes[MAXPLAYERS] ;
-
- #define EXPL_FRAMES 15
-
-
-
-
- /*------------------------------------------------------------------------------
- * Create explosion billboards.
- *----------------------------------------------------------------------------*/
- static void
- createExplosions(
- int rings,
- int spokes,
- int frames
- )
- {
- int frame ;
- float minR = (float)( 1.0f * CAR_LENGTH ) ;
- float maxR = (float)( 2.0f * CAR_LENGTH ) ;
- float r ;
- float alpha ;
- pfGeode *eg ;
-
- /*
- * create a new geostate from shared memory,
- * disable texturing and enable transparency
- */
- expGeoState = pfNewGState( pfGetSharedArena() ) ;
- pfGStateMode( expGeoState, PFSTATE_ENTEXTURE, 0 ) ;
- pfGStateMode( expGeoState, PFSTATE_TRANSPARENCY, PFTR_ON ) ;
- pfGStateMode( expGeoState, PFSTATE_ENLIGHTING, PF_OFF ) ;
- pfGStateMode( expGeoState, PFSTATE_CULLFACE, PFCF_BACK ) ;
-
- for( frame = 0 ; frame < frames ; frame++ )
- {
- r = minR + ( maxR - minR ) *
- pfSqrt( (float)frame / ( frames - 1.0f ) ) ;
- eg = makeExplosionFrame( rings, spokes, r,
- (float)frame / ( frames - 1.0f ) ) ;
- pfAddChild( explosionSwitch, eg ) ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Make an explosion frame.
- *----------------------------------------------------------------------------*/
- static pfGeode *
- makeExplosionFrame(
- int rings,
- int spokes,
- float r,
- float frame
- )
- {
- int i ;
- int j ;
- int ring ;
- int spoke ;
- long nPts ;
- long nIndices ;
- unsigned short *indices ;
- long *length ;
- float theta ;
- float radius ;
- float st ;
- float ct ;
- float y ;
- float alpha = 1.0f - frame * 0.8f ;
- pfGeode *geode ;
- pfGeoSet *gset ;
- pfVec3 *coords ;
- pfVec4 *colors ;
-
- geode = pfNewGeode() ;
-
- gset = pfNewGSet( pfGetSharedArena() ) ;
-
- length = (long *)myMalloc( rings * sizeof( long ) ) ;
-
- nPts = rings * spokes ;
- coords = (pfVec3 *)myMalloc( nPts * sizeof( pfVec3 ) ) ;
- colors = (pfVec4 *)myMalloc( nPts * sizeof( pfVec4 ) ) ;
-
- nIndices = spokes ;
- length[0] = spokes ;
- for( i = 1 ; i < rings ; i++ )
- {
- length[i] = 2 * ( spokes + 1 ) ;
- nIndices += length[i] ;
- }
- indices = (unsigned short *)myMalloc(
- nIndices * sizeof( unsigned short ) ) ;
-
- /*
- * Assign coordinate points and colors.
- */
- i = 0 ;
- j = 0 ;
- for( ring = 0 ; ring < rings ; ring++ )
- {
- radius = r * (float)( ring + 1 ) / (float)rings ;
- y = pfSqrt( r*r - radius*radius ) ;
- for( spoke = 0 ; spoke < spokes ; spoke++ )
- {
- theta = 360.0f * (float)spoke / (float)spokes ;
- pfSinCos( theta, &st, &ct ) ;
- PFSET_VEC3( coords[i],
- radius * st,
- y,
- CAR_HEIGHT / 2.0f + radius * ct ) ;
- PFSET_VEC4( colors[i],
- 1.00f * ( 1.0f - radius/r ),
- 0.88f * ( 1.0f - radius/r ) *
- ( 1.0f - 0.5f * frame ),
- 0.0f,
- alpha ) ;
- i++ ;
- }
- if( ring == 0 )
- {
- for( spoke = 0 ; spoke < spokes ; spoke++ )
- {
- indices[j] = ( ( spoke + 1 ) % 2 ) * spoke / 2 +
- ( spoke % 2 ) *
- ( spokes - ( ( spoke + 1 ) / 2 ) ) ;
- j++ ;
- }
- }
- else
- {
- for( spoke = 0 ; spoke <= spokes ; spoke++ )
- {
- indices[j++] = ( ring ) * spokes +
- ( spoke % spokes ) ;
- indices[j++] = ( ring - 1 ) * spokes +
- ( spoke % spokes ) ;
- }
- }
- }
-
- pfGSetPrimType( gset, PFGS_TRISTRIPS ) ;
- pfGSetNumPrims( gset, (long)rings ) ;
- pfGSetPrimLengths( gset, length ) ;
- pfGSetAttr( gset, PFGS_COORD3, PFGS_PER_VERTEX, coords, indices ) ;
- pfGSetAttr( gset, PFGS_COLOR4, PFGS_PER_VERTEX, colors, indices ) ;
- pfGSetGState( gset, expGeoState ) ;
-
- pfAddGSet( geode, gset ) ;
-
- return( geode ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Initialize explosions.
- *----------------------------------------------------------------------------*/
- void
- initExplosion(
- void
- )
- {
- int i ;
-
- for( i = 0 ; i < MAXPLAYERS ; i++ )
- {
- explosionGroup[i] = NULL ;
- }
-
- explosionDCS = pfNewDCS() ;
-
- explosionSwitch = pfNewSwitch() ;
- pfSwitchVal( explosionSwitch, PFSWITCH_OFF ) ;
- pfAddChild( explosionDCS, explosionSwitch ) ;
-
- createExplosions( 4, 32, EXPL_FRAMES ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Set explosion nodes for a player.
- *----------------------------------------------------------------------------*/
- void
- addExplosion(
- int n,
- pfScene *scene
- )
- {
- int i ;
- pfDCS *location ;
- pfGroup *frame ;
-
- if( explosionGroup[n] == NULL )
- {
- explosionGroup[n] = (pfDCS *)pfClone( explosionDCS, 0 ) ;
- pfAddChild( scene, explosionGroup[n] ) ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Set explosion frame and location.
- *----------------------------------------------------------------------------*/
- void
- setExplosionFrame(
- int n,
- float expTime
- )
- {
- int frame ;
- pfDCS *group ;
- pfMatrix m ;
- static float h = 0.75f * CAR_HEIGHT ;
- static float l = CAR_LENGTH / 6.0f ;
-
- frame = expTime * frameRate ;
-
- group = explosionGroup[n] ;
-
- if( frame >= EXPL_FRAMES )
- {
- pfSwitchVal( EXPLOSION_SWITCH( group ), PFSWITCH_OFF ) ;
- }
- else
- {
- pfSwitchVal( EXPLOSION_SWITCH( group ), frame ) ;
-
- /*
- * Set rotation so that it always faces viewer (3D billboard).
- */
- m[0][0] = -right[0] ;
- m[0][1] = -right[1] ;
- m[0][2] = -right[2] ;
-
- m[1][0] = -ahead[0] ;
- m[1][1] = -ahead[1] ;
- m[1][2] = -ahead[2] ;
-
- m[2][0] = -up[0] ;
- m[2][1] = -up[1] ;
- m[2][2] = -up[2] ;
-
- m[0][3] = 0.0f ;
- m[1][3] = 0.0f ;
- m[2][3] = 0.0f ;
-
- m[3][0] = player[n].xyz[0] +
- h * player[n].up[0] - l * player[n].ahead[0] ;
- m[3][1] = player[n].xyz[1] +
- h * player[n].up[1] - l * player[n].ahead[1] ;
- m[3][2] = player[n].xyz[2] +
- h * player[n].up[2] - l * player[n].ahead[2] ;
- m[3][3] = 1.0f ;
-
- pfDCSMat( group, m ) ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Start the explosion sequence for an enemy.
- *----------------------------------------------------------------------------*/
- void
- startExplosion(
- int n
- )
- {
- int i ;
- int k ;
-
- /*
- * Stop displaying vehicle and (possible)shield.
- */
- for( i = 0 ; i < pfGetNumChildren( trikeSwitch[n] ) ; i++ )
- {
- pfNodeTravMask( pfGetChild( trikeSwitch[n], 0 ), PFTRAV_DRAW,
- 0, PFTRAV_SELF, PF_SET ) ;
- }
- deadTime[n] = gameTime ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * End the explosion sequence for an enemy.
- *----------------------------------------------------------------------------*/
- void
- endExplosion(
- int n
- )
- {
- setExplosionFrame( n, 100.0f ) ;
-
- pfNodeTravMask( pfGetChild( trikeSwitch[n], 0 ), PFTRAV_DRAW,
- 0xffffffff, PFTRAV_SELF, PF_SET ) ;
- deadTime[n] = 0.0f ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Delete an explosion due to deleting a player.
- *----------------------------------------------------------------------------*/
- void
- deleteExplosion(
- int n,
- pfScene *scene
- )
- {
- int i ;
-
- if( pfRemoveChild( scene, explosionGroup[n] ) )
- {
- pfDelete( explosionGroup[n] ) ;
- }
- explosionGroup[n] = NULL ;
-
- for( i = n ; i < numberPlayers ; i++ )
- {
- explosionGroup[i] = explosionGroup[i+1] ;
- }
- }
-